/**
 * 减法算式类 - 继承自算式抽象类
 * 
 * 设计特点：
 * 1. 继承Expression抽象类
 * 2. 实现具体的减法运算逻辑
 * 3. 封装减法的业务规则
 * 4. 提供减法特有的操作符
 * 
 * 业务规则：
 * - 减法差不小于0
 * - 支持负数和正数运算
 */
package edu.scut.oop.exercise.v2;

public class SubtractionExpression extends Expression {
    
    /**
     * 构造函数
     * @param num1 被减数
     * @param num2 减数
     * @throws IllegalArgumentException 当减法结果小于0时抛出异常
     */
    public SubtractionExpression(int num1, int num2) {
        super(num1, num2);
        
        // 验证减法业务规则：结果不能小于0
        if (this.result < 0) {
            throw new IllegalArgumentException(
                String.format("减法结果不能小于0，但计算结果为%d：%d - %d = %d", 
                            this.result, num1, num2, this.result)
            );
        }
    }
    
    /**
     * 计算减法结果
     * @return 减法结果
     */
    @Override
    public int calculate() {
        return num1 - num2;
    }
    
    /**
     * 判断是否为加法
     * @return 始终返回false
     */
    @Override
    public boolean isAddition() {
        return false;
    }
    
    /**
     * 判断是否为减法
     * @return 始终返回true
     */
    @Override
    public boolean isSubtraction() {
        return true;
    }
    
    /**
     * 获取减法操作符
     * @return "-"字符串
     */
    @Override
    public String getOperatorSymbol() {
        return "-";
    }
    
    /**
     * 验证减法算式是否有效
     * @return true表示有效（差不小于0），false表示无效
     */
    @Override
    public boolean isValid() {
        return result >= 0 && result == (num1 - num2);
    }
    
    /**
     * 重写setNum1方法，确保修改被减数后仍然满足减法规则
     */
    @Override
    public void setNum1(int num1) {
        int newResult = num1 - this.num2;
        if (newResult < 0) {
            throw new IllegalArgumentException(
                String.format("修改被减数后减法结果不能小于0：%d - %d = %d", 
                            num1, this.num2, newResult)
            );
        }
        super.setNum1(num1);
    }
    
    /**
     * 重写setNum2方法，确保修改减数后仍然满足减法规则
     */
    @Override
    public void setNum2(int num2) {
        int newResult = this.num1 - num2;
        if (newResult < 0) {
            throw new IllegalArgumentException(
                String.format("修改减数后减法结果不能小于0：%d - %d = %d", 
                            this.num1, num2, newResult)
            );
        }
        super.setNum2(num2);
    }
    
    /**
     * 获取减法特有的描述信息
     * @return 描述字符串
     */
    public String getDescription() {
        return String.format("减法算式：%d - %d = %d", num1, num2, result);
    }
    
    /**
     * 检查减法算式是否可以交换操作数（变成加法）
     * @return true表示可以交换
     */
    public boolean canSwapOperands() {
        // 如果num2 + result = num1，那么可以交换
        return num2 + result == num1;
    }
    
    /**
     * 交换操作数（生成一个结果相同的减法算式）
     * @return 交换操作数后的新减法算式
     */
    public SubtractionExpression swapOperands() {
        if (!canSwapOperands()) {
            throw new IllegalStateException("操作数不能交换，因为会违反减法规则");
        }
        // 创建一个结果相同的减法算式: 0 - (-result) = result
        return new SubtractionExpression(0, -result);
    }
    
    /**
     * 获取减法中被减数比减数大的程度
     * @return 差值
     */
    public int getDifference() {
        return Math.abs(result);
    }
}